package howl.Servlets;

import howl.model.Handler;
import howl.model.Model;
import howl.model.PMF;
import howl.types.HowlUser;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;

import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.jdo.Query;
import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

import compiler.HowlCompiler;
import compiler.HowlToken;
import compiler.exceptions.HowlException;
import compiler.exceptions.HowlModelException;
import compiler.exceptions.HowlUnauthorisedAction;

@SuppressWarnings("serial")
public class HowlMailHandler extends HttpServlet {

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		Properties props = new Properties(); 
        Session session = Session.getDefaultInstance(props, null); 
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
			MimeMessage message = new MimeMessage(session, req.getInputStream());
			StringOutputStream sos = new StringOutputStream();
			ByteArrayInputStream bais  = (ByteArrayInputStream) message.getContent();
			
			int length = bais.available();
			byte [] buff = new byte[length];
			bais.read(buff);
			
			String str = new String(buff);
			String lookfor = "Content-Type: text/plain; charset=ISO-8859-1\n\n";
			str = str.substring(str.indexOf(lookfor)+lookfor.length());
			str= str.substring(0,str.indexOf("\n"));
	           

	      
			HowlUser hu = Model.getHowlUserfromEmail(getSender(message));
			

			
			if (hu != null) {
					try {
						HowlCompiler compiler = new HowlCompiler();
						Handler h = new Handler(hu);
						List<HowlToken> ht = compiler.parse(str);
						for(HowlToken hs : ht) {
							h.Handle(hs);
						}

					} catch (HowlException e) {
						Message msg = new MimeMessage(session);
			            msg.setFrom(new InternetAddress("UoWhowl@googlemail.com", "Howl Admin"));
			            msg.addRecipient(Message.RecipientType.TO,
	                             new InternetAddress(hu.getEmailAddress(), hu.getUsers().getNickname()));
			            msg.setSubject("Message from Howl Administrator");
			            msg.setText("A Message was sent which was not in the correct format or contained syntax errors. The message was: "+ str);
			            Transport.send(msg);
					} catch (HowlUnauthorisedAction e) {
						Message msg = new MimeMessage(session);
			            msg.setFrom(new InternetAddress("UoWhowl@googlemail.com", "Howl Admin"));
			            msg.addRecipient(Message.RecipientType.TO,
	                             new InternetAddress(hu.getEmailAddress(), hu.getUsers().getNickname()));
			            msg.setSubject("Message from Howl Administrator");
			            msg.setText("A Message was sent to Howl which this account does not have the permissions to execute");
			            Transport.send(msg);
					} catch (HowlModelException e) {
					
						e.printStackTrace();
					}

			}else{
				Message msg = new MimeMessage(session);
	            msg.setFrom(new InternetAddress("UoWhowl@googlemail.com", "Howl Admin"));
	            msg.addRecipient(Message.RecipientType.TO,
                        new InternetAddress(getSender(message), ""));
	            msg.setSubject("Message from Howl Administrator");
	            msg.setText("Your currently not a user of this service " + getSender(message));
	            Transport.send(msg);
			}
			 
			
		} catch (MessagingException e) {
			
		}
	
	}
	
	
	private String getSender(MimeMessage m){
		String str;
		try {
			str = m.getFrom()[0].toString();
			return str.substring(str.indexOf("<")+1,str.length()-1 );
		} catch (MessagingException e) {
			return null;
		}

        
	}
	
	private void SendError(MimeMessage m){
		MimeMessage reply;
		try {
			reply = (MimeMessage)m.reply(false);
			reply.setFrom(new InternetAddress("uowhowl@googlemail.com"));
			StringOutputStream sos = new StringOutputStream();
			m.writeTo(new StringOutputStream());
			reply.setText("A Message was sent to Howl which wasnt in the correct format, the Message was: " + sos.getString());
			Transport.send(reply);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	class StringOutputStream extends OutputStream {

		  StringBuilder mBuf;

		  public void write(int b) throws IOException {
		    mBuf.append((char) b);
		  }

		  public String getString() {
		    return mBuf.toString();
		  }

		
		}
}
